//
//  AirData.h
//  AirCpp
//
//  Created by Penghao on 14-3-26.
//  Copyright (c) 2014年 PengHao. All rights reserved.
//

#ifndef __AirCpp__AirData__
#define __AirCpp__AirData__

#include <iostream>
#include "../AirObject/AirObject.h"
#include "AirArray.h"
namespace AirCpp{
    typedef struct Range{
        AirSize_t offset;
        AirSize_t length;
        Range(AirSize_t off, AirSize_t len){
            offset = off;
            length = len;
        };
    }AirRange;
    
    class AirData : public AirObject{
    protected:
        AirSize_t pice_block_size;
    public:
        
        AirBit8 *p_current;
        AirBit8 *c_data;
        AirSize_t length;
        
        AirData():length(-1), c_data(NULL), p_current(NULL), pice_block_size(sizeof(AirBit8)){
            
        };
        ~AirData(){
            if (c_data!=NULL) {
                free(c_data);
            }
        }
        
        operator void *(){return c_data;}
        
        void clear_data(){
            memset(c_data, 0, length);
        }
        
        int init(AirSize_t data_size){
            data_size+=pice_block_size/2;
            data_size/=pice_block_size;
            c_data = (AirBit8 *)calloc(data_size, pice_block_size);
            if (c_data == NULL) {
                return -1;
            }
            p_current = c_data;
            length = data_size;
            return 0;
        }
        
        int init(const void *data, AirSize_t data_size){
            c_data = (AirBit8 *)malloc(data_size);
            if (c_data == NULL) {
                return -1;
            }
            memset(c_data, 0, data_size);
            length = data_size;
            memcpy(c_data, data, data_size);
            return 0;
        }
        
        bool is_contented_data(const void *data){
            return true;
        }
        
        AirSize_t append_c_data(const AirBit8 *data, AirSize_t data_size){
            if (data_size > (p_current - c_data)*pice_block_size) {
                return -1;
            }else{
                memcpy(p_current, data, data_size);
                p_current += data_size;
                return data_size;
            }
        }
        
        AirSize_t read_c_data_to_traget(AirRange range, AirBit8 *target_c_data){
            AirSize_t left_size = length - range.offset;
            AirSize_t copy_size = range.length<=left_size?range.length:left_size;
            memcpy(target_c_data, c_data+range.offset, copy_size);
            return copy_size;
        }

        AirSize_t read_data_to_traget(AirSize_t data_size, AirSize_t offset, AirData *target_data){
            if (data_size <= length - offset) {
                if (target_data->append_c_data(c_data+offset, data_size) == 0) {
                    return data_size;
                }else{
                    return -1;
                }
            }else{
                return length - offset;
            }
        }
    };
}
#endif /* defined(__AirCpp__AirData__) */
